Release 10.1A: OpenEdge Getting Started:
Object-oriented Programming


Defining data members within a class

Data members define the instance data of a class. They must be defined in the main block of the class. You can define ProDataSets, temp-tables, queries, buffers, data sources, variables, streams, work tables, and static GUI objects as data members of a class, with restrictions as noted below.

Data members of a class are defined using the standard Progress DEFINE statements, with the addition of an optional access modifier for each data member. The access modifier is valid only for definitions in the main block of a class file. The access modifiers are PRIVATE, PROTECTED and PUBLIC. PRIVATE data members can only be accessed by the class defining them. PROTECTED data members can be accessed by the class defining them and by any class that inherits from that class. PUBLIC data members can be accessed by the class defining them, by any class that inherits from that class, and by any class or procedure that instantiates that class using an object reference. For more information, see the "Accessing class data members" section.

By default, data members in a class are PRIVATE. A PRIVATE data member can be accessed within the class, including its methods, but not from any other class.

Temp-tables and ProDataSets must be defined as data members of the class. They cannot be defined within a method of a class. This is also equivalent to the restriction for procedures that temp-tables and ProDataSets cannot be defined within internal procedures and user-defined functions.

This is the syntax for defining a variable data member:

Syntax
DEFINE [ PRIVATE | PROTECTED | PUBLIC ] { VARIABLE } 
    data-member-name data-member-definition . 

This is the syntax for defining other non-visual data members, which cannot be defined as PUBLIC:

Syntax
DEFINE [ PRIVATE | PROTECTED ]  
    { BUFFER | TEMP-TABLE | QUERY | DATASET | DATA-SOURCE } 
    data-member-name data-member-definition . 

This is the syntax for defining visual widgets and other data members that cannot be defined as PUBLIC or PROTECTED:

Syntax
DEFINE [ PRIVATE ] 
    { BROWSE | BUTTON | FRAME | IMAGE | MENU |  
       RECTANGLE | STREAM | SUB-MENU | WORK-TABLE }  
    data-member-name [ data-member-definition ] .  

Element descriptions for these data member syntax diagrams follow:

[ PRIVATE | PROTECTED | PUBLIC ]

The optional modifier defines the access mode for the data member. The default access mode is PRIVATE. PRIVATE data members can only be accessed by the class defining the data member. PROTECTED data members can be accessed by the class defining them and by any class that inherits from that class. PUBLIC data members can be accessed by the class defining them, by any class that inherits from that class, and by other classes and procedures that reference that class.

Only data members in the main block of a class can have an access mode. Local variables defined within methods cannot have an access mode. They are always scoped privately to the method, similar to the way local definitions within an internal procedure or function are locally scoped.

Visual and other objects that share the same definition syntax can only be defined as PRIVATE. That means that these visual objects, streams, and work-tables can only be used within the class file that defines them. For more information on using visual objects within a class file, see the "Defining and using visual objects in classes" section.

data-member-name

The name of the variable, buffer, temp-table, query, ProDataSet, data-source, visual object, stream, or work-table.

The data-member-name must be unique among all data members in the class and its class hierarchy.

If you define a PRIVATE or PROTECTED ProDataSet, then the temp-tables and buffers of the ProDataSet must also be defined with the same access mode.

There is limited support for the PUBLIC access mode. It is only valid when defining a variable. However, defining a PUBLIC variable with an EXTENT is also not supported.

data-member-definition

The rest of the syntax required for the variable, buffer, temp-table, query, ProDataSet and data source.

For example, adding three data members to our sample class definition would result in this code:

CLASS acme.myObjs.CustObj INHERITS acme.myObjs.Common.CommonObj: 
    DEFINE PUBLIC VARIABLE iNumCusts AS INTEGER NO-UNDO. 
    DEFINE PROTECTED TEMP-TABLE ttCust NO-UNDO 
        FIELD CustNum LIKE Customer.CustNum 
        FIELD Name LIKE Customer.Name. 
    DEFINE PRIVATE VARIABLE rError  
        AS CLASS acme.myObjs.Common.ErrorObj NO-UNDO. 
    ... 
END CLASS. 

For PUBLIC and PROTECTED definitions the data member name scopes to the class that defines it and to all subclasses of this class. The definition of a PUBLIC or PROTECTED data member does not need to be repeated in the subclass or the referencing class. The use of the data member name in a subclass refers to the data member defined in the subclass or to data members defined in a super class within its class hierarchy. There is no separate copy of the data member when it is referenced from a subclass. If a subclass references a data member from a super class, the compiler accesses the data member definition in the super class to identify its type information. If the data member definition is repeated in the subclass, this results in a compiler error.

When a PUBLIC data member is accessed outside of its class hierarchy, it is accessed through an object reference, using the object-reference:data-member-name syntax. The data member is defined in the referenced class and no separate copy is made in the referencing class. That is, the referencing class does not repeat the definition for a data member that it references in another object. A data member definition of the same name in the referencing class is treated as an entirely separate data member from the one in the referenced class.

For example, take the previous class definition for acme.myObjs.CustObj and define a new class acme.myObjs.NECustomer that inherits and references the data members of its super class acme.myObjs.CustObj. If the class acme.myObjs.CustObj defines behavior for handling Customer data in the application, the new subclass acme.myObjs.NECustomer can be thought of as a specialization of that class that defines additional or overridden behavior just for Customer records for the New England area.

Notice that both the PUBLIC and PROTECTED data members, iNumCusts and ttCust, are accessible within the new subclass, acme.myObjs.NECustomer:

CLASS acme.myObjs.NECustomer INHERITS acme.myObjs.CustObj: 
    METHOD PRIVATE VOID DisplayCust ( ): 
        iNumCusts = iNumCusts + 1. 
        FOR EACH ttCust: 
            DISPLAY ttCust. 
        END. 
    END METHOD. 
END CLASS. 

Following is a separate class, MyMain, that uses the NEW statement to create an instance of the class acme.myObjs.NECustomer. In this case only the PUBLIC data member iNumCusts of acme.myObjs.NECustomer is accessible to this class:

CLASS MyMain: 
    DEFINE VARIABLE rNECust AS CLASS acme.myObjs.NECustomer NO-UNDO. 
    METHOD PRIVATE VOID DisplayCust ( ): 
        clNECust = NEW acme.myObjs.NECustomer( ). 
        clNECust:iNumCusts = rNECust:iNumCusts + 1. 
        /* Can not access PROTECTED ttCust */ 
        DELETE OBJECT rNECust. 
        clNECust = ?. 
    END METHOD. 
END CLASS. 

Comparison with procedure-based programming

The variables and other data elements defined in the main block of an external procedure are private without having an explicit access modifier. That is, they are scoped to the procedure, including its internal procedures and user-defined functions, but cannot be accessed directly from other external procedures. In the same way, data members in a class with no access modifier are PRIVATE and accessible from all methods defined in the class, but cannot be accessed directly from other classes both inside or outside the class hierarchy.

Procedures can define SHARED variables, which are scoped to and accessible from other external procedures. The variable definitions must be defined as NEW SHARED in a parent procedure and the definitions repeated as SHARED in each called external procedure that needs to access them. This is necessary because the compiler does not look at other external procedures when compiling a procedure.

Classes do not support SHARED variables. PROTECTED and PUBLIC data members in classes provide wider scoping for access to class data members and without the need to repeat the data member definitions. However, they must be referenced with respect to the instantiated object where they are defined. So, for PROTECTED data members, they can only be referenced within the class hierarchy of a single instantiated object where they are defined; and for PUBLIC data members, from outside their class hierarchy, they can only be referenced using an object reference to the instantiated class in whose class hierarchy they are defined. These referential restrictions both conform to class and object relationships and allow the compiler to validate data member references for consistency based on these relationships.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095